<template>
  <div
    class="tr-tabs"
    :class="{
      'z-forcedPc': !$q.platform.is.mobile && mappingProps.forcedPc,
      'z-mobile': isMobile,
      'z-crosswise': tabPosition === 'top' || tabPosition === 'bottom',
      'z-vertical': tabPosition === 'left' || tabPosition === 'right',
    }"
    v-show="mappingProps.visible"
    :style="mappingProps.style"
    tabIndex="-1"
  >
    <!-- 标签页组件 -->

    <!-- 顶部 -->
    <template v-if="mappingProps.tabPosition === 'top'">
      <q-card :flat="cardIsFlat" :bordered="mappingProps.type === 'bordered'">
        <div class="tabs-wrap">
          <t-tabs
            v-bind="{ ...mappingProps }"
            narrowIndicator
            :staticItems="visibleStaticItems"
            v-model="currentTabIndex"
            :tabIndex="mappingProps.tabIndex"
          ></t-tabs>
        </div>

        <q-separator
          :color="mappingProps.separatorColor"
          :size="mappingProps.separatorSize"
          v-if="visibleSeparator"
        />

        <q-tab-panels
          v-if="!mappingProps.hideTabPanel"
          v-model="currentTabCode"
          :swipeable="mappingProps.swipeable"
          keep-alive
          :style="panelStyle"
        >
          <slot></slot>
        </q-tab-panels>
      </q-card>
    </template>

    <!-- 底部 -->
    <template v-if="mappingProps.tabPosition === 'bottom'">
      <q-card :flat="cardIsFlat" :bordered="mappingProps.type === 'bordered'">
        <q-tab-panels
          v-if="!mappingProps.hideTabPanel"
          v-model="currentTabCode"
          :swipeable="mappingProps.swipeable"
          :style="panelStyle"
        >
          <slot></slot>
        </q-tab-panels>

        <q-separator
          :color="mappingProps.separatorColor"
          :size="mappingProps.separatorSize"
          v-if="visibleSeparator"
        />

        <div class="tabs-wrap">
          <t-tabs
            v-bind="{ ...mappingProps }"
            :staticItems="visibleStaticItems"
            narrowIndicator
            v-model="currentTabIndex"
            :tabIndex="mappingProps.tabIndex"
          ></t-tabs>
        </div>
      </q-card>
    </template>

    <!-- 左侧 -->
    <template v-if="mappingProps.tabPosition === 'left'">
      <q-card :flat="cardIsFlat" :bordered="mappingProps.type === 'bordered'">
        <q-splitter v-model="splitterModel" :separator-class="separatorClass">
          <template v-slot:before>
            <t-tabs
              v-bind="{ ...mappingProps }"
              :staticItems="visibleStaticItems"
              v-model="currentTabIndex"
              vertical
              :tabIndex="mappingProps.tabIndex"
            ></t-tabs>
          </template>

          <template v-slot:after>
            <q-tab-panels
              v-if="!mappingProps.hideTabPanel"
              v-model="currentTabCode"
              vertical
              :swipeable="mappingProps.swipeable"
              :style="panelStyle"
            >
              <slot></slot>
            </q-tab-panels>
          </template>
        </q-splitter>
      </q-card>
    </template>
    <!-- 右侧 -->

    <template v-if="mappingProps.tabPosition === 'right'">
      <q-card :flat="cardIsFlat" :bordered="mappingProps.type === 'bordered'">
        <q-splitter
          v-model="splitterModel"
          :separator-class="separatorClass"
          reverse
        >
          <template v-slot:before>
            <q-tab-panels
              v-if="!mappingProps.hideTabPanel"
              v-model="currentTabCode"
              vertical
              :swipeable="mappingProps.swipeable"
              :style="panelStyle"
            >
              <slot></slot>
            </q-tab-panels>
          </template>

          <template v-slot:after>
            <t-tabs
              v-bind="{ ...mappingProps }"
              :staticItems="visibleStaticItems"
              v-model="currentTabIndex"
              :tabIndex="mappingProps.tabIndex"
              vertical
            ></t-tabs>
          </template>
        </q-splitter>
      </q-card>
    </template>
  </div>
</template>

<!-- ts只是方便开发提示和补全代码，没有用语法 -->

<script setup type="typescript">
import { computed, onMounted, useAttrs, ref, nextTick, watch, reactive } from 'vue';
// 钩子函数、小工具
import { useQuasar } from '@teld/q-components';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
	commonProps
} from 't/common/utils';
// 组件
import TTabs from './tabs.vue';
import QTabPanels from '@teld/q-components/TabPanels';
import QCard from '@teld/q-components/Card';
import QSplitter from '@teld/q-components/Splitter';
// 内部子组件通用样式
import sharedProps from './props';

const Funcs = window.Funcs || {
  GetTerms: (c, n) => n,
};

const $q = useQuasar();

// 直接映射透传qursor的属性
const attrs = useAttrs();
// 组件传参
const props = defineProps(
	{
		...commonProps,
		...sharedProps,

		// 是否可见
		visible: {
			type: Boolean,
			default: true,
		},

		tabPosition: {
			type: String,
			default: 'top',
		},

		modelValue: {
			type: Number,
			default: 0,
		},

		// 是否显示分割线
		visibleSeparator: {
			type: Boolean,
			default: false,
		},

		separatorColor: {
			type: String,
			default: '#f1f1f1'
		},

		separatorSize: {
			type: String,
			default: '1px'
		},

		swipeable: {
			type: Boolean,
			default: false
		},

		tabIndex: {
			type: [String, Number],
			default: '1'
		},

		forcedPc: {
			type: Boolean,
			default: true
		},
	}
);
// 大写首字母属性
const [mappingProps, mappingExpose] = useMappingProps(props);

// 浏览宽度低于768px
const isMobile = computed((() => !mappingProps.forcedPc && $q.screen.xs) || $q.platform.is.mobile);

// 是否设计时
const inDesign = !!window['fas']?.inDesign;

// 外层的card是否是无阴影模式
const cardIsFlat = computed(() => mappingProps.type === 'none' || mappingProps.type === 'bordered')

// 标签内容的样式
const panelStyle = computed(() => {
	const { fillMode, fillMarginBottom, height } = mappingProps;
	const minHeight = inDesign ? "50px" : 0;
	if (fillMode === 'none') return { minHeight };
	if (fillMode === 'auto') return { paddingBottom: fillMarginBottom, minHeight };
	if (fillMode === 'fixedHeight') return { height, minHeight };
});

// 是否显示分割线
const visibleSeparator = computed(() => {
	return mappingProps.visibleSeparator
	//  && !mappingProps.hideTabLabel
	// 	 && !mappingProps.hideTabPanel

});

// 左右布局时，分割比例
const splitterModel = computed(() => {
	return mappingProps.hideTabLabel ? 0 : 'auto';
});
// 左右布局时，分割线class
const separatorClass = computed(() => {
	return !visibleSeparator.value ? 'u-separator-none' : 'u-separator-default';
});

// 列表数据源
function computeStaticItems() {
	return (mappingProps?.staticItems || []).map(v => ({
		...v,
		code: v.code ?? v.ID,
		label: Funcs.GetTerms(v.label=='标签' ? 'Schema.Controls.fasr_tabs.tab' : v.ValueInfo_label?.ReferenceExpr, v.label)
	}));
}
const staticItems = ref(computeStaticItems());
watch(() => mappingProps.staticItems, (val, oldVal) => {
	try {
		if (JSON.stringify(val) != JSON.stringify(oldVal)) {
			staticItems.value = computeStaticItems()
		}
	} catch (e) { }
})

const visibleStaticItems = computed(() => staticItems.value.filter(v => !v.hidden));

// 当前节点index
let currentTabIndex = ref(mappingProps.modelValue ?? 0);
watch(visibleStaticItems, () => {
	if (currentTabIndex.value >= visibleStaticItems.value.length) {
		currentTabIndex.value = visibleStaticItems.value.length - 1;
	}
})
// console.log------------------- currentTabIndex', currentTabIndex)
let loadedTabIndexs = reactive(new Set([currentTabIndex.value]));

// 当前tab的唯一标识符
const currentTabCode = computed({
	// getter
	get() {
		return visibleStaticItems.value[currentTabIndex.value]?.code
	},
	// setter
	set(newValue) {
		// 注意：我们这里使用的是解构赋值语法
		currentTabIndex.value = visibleStaticItems.value.findIndex(v => v.code === newValue)
	}
})
// 当前tab的Name
const currentTabName = computed({
	// getter
	get() {
		return visibleStaticItems.value[currentTabIndex.value]?.label
	},
	// setter
	set(newValue) {
		// 注意：我们这里使用的是解构赋值语法
		currentTabIndex.value = visibleStaticItems.value.findIndex(v => v.label === newValue)
	}
})

// 设置某个tab隐藏或显示 例：({label:'标签2'}, false) => 将label为标签2的标签设置hidden为true
function setTabVisible(condition, bool) {
	let index = null;
	if (typeof condition === 'number') index = condition;
	if (typeof condition === 'object') {
		Object.entries(condition).forEach(([k, v]) => {
			if (k === 'index') return index = v;
			if (k === 'label') return staticItems.value.forEach((item, i) => {
				if (item.label === v) index = i;
			})
		})
	}
	if (index !== null && staticItems.value[index]) staticItems.value[index].hidden = !bool;
}

// tab模式：切换tab事件
function handleChangeTab(index) {
	currentTabIndex.value = index;
}

// ------------------- 要暴露的方法 -------------------
// 修改tab的label属性，入参：要修改tab的标识符，修改后的label名称
function changeTabLabel(index, label) {
	if (typeof index === 'undefined') return;
	if (index === -1) return;
	staticItems.value.splice(index, 1, { ...staticItems.value[index], label })
	// alert('changeTabLabel:' + staticItems.value[index].label)
}
defineExpose({ ...mappingExpose, staticItems, currentTabIndex, currentTabCode, currentTabName, loadedTabIndexs, changeTabLabel, setTabVisible });


// ------------------- 回调事件 -------------------
// 触发的emit事件
const emit = defineEmits(['change', 'update:modelValue']);
// 点击事件
function onChangeHandler(params) { emit('change', params) }
watch(currentTabIndex, (val, oldVal) => {
	if (val != oldVal) {
		loadedTabIndexs.add(val)
		onChangeHandler(val)
		if (mappingProps.modelValue != val) {
			// console.log('currentTabIndex 改变啦', val)
			emit('update:modelValue', val)
		}
	}
})
watch(() => mappingProps.modelValue, (val, oldVal) => {
	if (val != currentTabIndex.value) {
		// console.log('mappingProps.modelValue 改变啦', val)
		currentTabIndex.value = val;
	}
})
</script>

<style lang="scss">
body.desktop .tr-tabs .q-focusable:focus>.q-focus-helper{
  background: none!important;
}
.tr-tabs {
  width: 100%;
  .q-hoverable:hover>.q-focus-helper{
    background: none!important;
  }
  .q-focusable:focus>.q-focus-helpe{
    background: none!important;
  }
  &.z-forcedPc {
    .q-tabs__content--align-justify .q-tab {
      flex: none;
    }
  }

  .u-separator-none {
    width: 0;
    height: 0;
  }

  .u-separator-default {
    background-color: #f1f1f1;
  }

  .q-tab__label {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    word-wrap: normal;
  }

  .q-tabs {
    .q-tab {
      min-height: 42px;

      &[aria-selected='true'] {
        .q-tab__label {
          // font-weight: bold;
        }
      }

      .q-tab__label {
        font-size: 14px;
      }

      .q-tab__indicator {
        // max-width: 38px;
        height: 4px;
        // border-radius: 2px;
        margin: auto;
      }

      .q-icon {
        width: 14px;
        height: 14px;
        font-size: 14px;

        &.material-icons {
          width: 18px;
          height: 18px;
          font-size: 18px;
        }
      }
    }

    &.q-tabs--vertical {
      .q-tab {
        .q-tab__indicator {
          height: auto;
        }
      }
    }
  }

  .q-tabs__arrow {
    margin: auto;
    width: 32px;
    min-width: 32px;
    height: 32px;
    line-height: 32px;
    background-color: #fff;
    color: rgba(#000, 0.32);
    // font-size: 28px;
    font-size: 14px;
  }

  .q-tab-panel {
    padding: 0;
  }

  // 系统样式 纵向默认
  &.z-vertical {
    .q-tabs--vertical .q-tab {
      padding: 0 24px;
      margin-bottom: 24px;
      min-height: 38px;

      .q-tab__indicator {
        width: 4px;
      }
    }
  }

  // 手机端
  &.z-mobile {
    .tabs-wrap {
      padding: 3px 0;
    }

    .q-tab {
      &[aria-selected='true'] {
        .q-tab__label {
          color: rgba(#000, var(--t-color-opacity, /*批量处理90%透明度*/0.9));
        }
      }
    }
  }

  // 系统样式 一级标签
  &.tr-tabs-level1 {
    &.z-crosswise {
      > .q-card > .tabs-wrap .q-tab {
        min-height: 42px;

        .q-tab__label {
          font-size: 16px;
        }
      }
    }

    &.z-mobile {
      > .q-card > .tabs-wrap .q-tab {
        .q-tab__label {
          font-size: 16px;
        }
      }
    }
  }

  // 系统样式 三级标签
  &.tr-tabs-level3 {
    &.z-crosswise {
      > .q-card > .tabs-wrap .q-tab {
        min-height: 32px;

        .q-tab__label {
          font-size: 14px;
        }

        .q-tab__indicator {
          height: 0;
        }
      }
    }
  }

  // 系统样式 标准边距
  &.tr-tabs-padding-normal {
    > .q-card > .q-tab-panels > .q-panel > .q-tab-panel,
    > .q-card
      > .q-splitter
      > .q-splitter__panel
      > .q-tab-panels
      > .q-panel
      > .q-tab-panel {
      padding: 16px 24px;
    }

    &.z-mobile {
      > .q-card > .q-tab-panels > .q-panel > .q-tab-panel,
      > .q-card
        > .q-splitter
        > .q-splitter__panel
        > .q-tab-panels
        > .q-panel
        > .q-tab-panel {
        padding: 16px 16px 15px 16px;
      }
    }
  }
}

.q-tab {
  color: rgba(#000, 0.56);
}
</style>
